/*

    This file is part of Hometree.

    Hometree is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Hometree is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Hometree.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2011,2012 Roman Held

*/
/********************************************************************\
                          Includes
\********************************************************************/
#include <assert.h>
#include <time.h>                 // nanosleep
#include <QCoreApplication>
#include <QTime>
#include "htr/capi.h"
#include "htr/htrclient.h"
#include "htr/htrmimedataresource.h"
#include "capi_types.h"
#include "capi_signalhandler.h"

/********************************************************************\
                          Definitions
\********************************************************************/

/********************************************************************\
                           MAKROS
\********************************************************************/
#define MIME_RES(r)  dynamic_cast<HtrMimeDataResource*>((r)->res) 

extern "C" {

/********************************************************************\
                        Implementation
\********************************************************************/

/*--------------------------------------------------------------------
*/
void    htrInit(int argc,char *argv[])
{
  if (!qApp)
    new QCoreApplication(argc,argv);
}

/*--------------------------------------------------------------------
*/
int  htrSleep(int mSecs)
/*
  Waits and processes qt-events for "mSecs" (minimum).
  Returns the real sleeptime...
*/
{
  assert(qApp); 
  int timeToSleep = mSecs; 
  QTime t;
  t.start();
  do {
    qApp->processEvents();
    int breakTime = timeToSleep > 10 ? 10:timeToSleep;
    usleep(breakTime*1000);
    timeToSleep = mSecs - t.elapsed(); 
  } while (timeToSleep > 0); 

  return t.elapsed();
}

/*--------------------------------------------------------------------
*/
void    htrClientCreate(sHtrClient *c)
{
  assert(c);
  *c = new sHtrClientHandler();
}

/*--------------------------------------------------------------------
*/
void   htrClientConnect(sHtrClient c, char *host, int port)
{
  assert(c);
  c->client.connectToHost(host,port);
}

/*--------------------------------------------------------------------
*/
void    htrClientDestroy(sHtrClient *c)
{ 
  assert(c);
  assert(0 && "not implemented");
}


// Resource
/*--------------------------------------------------------------------
*/
void    htrResStateCallback(sHtrResource r, fHtrResCallback cb)
{
  assert(r);
  assert(cb);
  r->sigHandler->registerStateCallback(cb);
}

/*--------------------------------------------------------------------
*/
void    htrResValueCallback(sHtrResource r, fHtrResCallback cb)
{
  assert(r);
  assert(cb);
  r->sigHandler->registerValueCallback(cb);
}

void    htrMimeDataCreate(sHtrResource *r, sHtrClient c, const char *url)
{
  assert(r);
  assert(c);
  assert(url);

  *r = new sHtrResourceHandler;
  (*r)->res = new HtrMimeDataResource();
  (*r)->sigHandler = new HtrPrivateSignalHandler();
  MIME_RES(*r)->init(&c->client,url);
  (*r)->sigHandler->init(*r);
}

/*--------------------------------------------------------------------
*/
void htrMimeDataOpen(sHtrResource r,int modes)
{
  assert(r);

  MIME_RES(r)->open(QFlags<Htr::Res::OpenModeFlag>(modes));
}

/*--------------------------------------------------------------------
*/
double  htrMimeDataDoubleValue(sHtrResource r, int */*error*/)
{
  assert(r);

  // TODO: Error-Handling? Mime-Checking?
  QByteArray content = MIME_RES(r)->mimeData();
  QDataStream stream(&content,QIODevice::ReadOnly);
  double ret;
  stream >> ret;
  return ret;
}

} // extern C
